#include <bits/stdc++.h>
#define _for(i, a, b)  for (int i = (a); i <= (b); i ++ )
#define PII pair<int, int>
#define mp make_pair
#define fi first
#define se second
#define pb push_back
using namespace std;
const int N = 2e5 + 5, C = 16;
int n, q, c, top, a[N], vis[1 << C], ans[N]; vector<PII > qry[1 << C], col[C][C];
struct Node { int u, v, sz; } del[N];
struct DSU {
	int fa[N], sz[N];
	inline void init() { _for (i, 1, n)  fa[i] = i, sz[i] = 1; }
	inline int find(int u) { while (u ^ fa[u])  u = fa[u]; return u; }
	inline int SZ(int u) { return sz[find(u)]; }
	inline void merge(int u, int v) {
		u = find(u), v = find(v);
		if (sz[u] > sz[v])  swap(u, v);
		if (u ^ v)  del[ ++ top] = (Node){u, v, sz[v]}, fa[u] = v, sz[v] += sz[u];
	}
} dsu;
void dfs(int S, int pre) {
	vis[S] = 1; int cur = top;
	if (S) {
		int t = __lg(S ^ pre);
		_for (i, 0, c - 1)  if ((S >> i) & 1)  for (PII j : col[i][t])  dsu.merge(j.fi, j.se);
	} for (PII i : qry[S])  ans[i.se] = dsu.SZ(i.fi);
	_for (i, 0, c - 1)  if ( ! ((S >> i) & 1) && ! vis[S | (1 << i)])  dfs(S | (1 << i), S);
	while (top > cur)  dsu.fa[del[top].u] = del[top].u, dsu.sz[del[top].v] = del[top].sz, top -- ;
}
int main() {
	freopen("tree.in", "r", stdin), freopen("tree.out", "w", stdout);
	ios :: sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> q >> c, dsu.init(); int S, u;
	_for (i, 1, n)  cin >> a[i];
	_for (i, 2, n)  cin >> u, col[a[u]][a[i]].pb(mp(u, i)), col[a[i]][a[u]].pb(mp(u, i));
	_for (i, 1, q) {
		cin >> S >> u;
		if ( ! ((S >> a[u]) & 1))  ans[i] = 1;
		else  qry[S].pb(mp(u, i));
	} dfs(0, 0);
	_for (i, 1, q)  cout << ans[i] << "\n";
	return 0;
}

